package com.dingding.common.core.util.amap;

import java.math.BigDecimal;
import java.util.List;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingding.common.core.util.HttpTool;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.common.core.util.UrlMaker;
import com.dingding.common.core.util.amap.amapDto.GetDistanceDto;

/**
 * @Description:高德地图接口的api
 * @author fengshuonan
 * @date 2016年7月27日 下午2:22:39
 * @version 叮叮搭车
 * @since 2.3.2
 */
public class AmapApi {

	private static final Logger log = Logger.getLogger(AmapApi.class);

	/**
	 * @Description: 搜索某地方属于哪个城市
	 * @param placeName 被搜索的地区名称
	 * @author fengshuonan
	 * @return String 城市名称
	 * @since 2.3.2
	 */
	public static String getCityName(String placeName) {
		if (getPlaceDetail(placeName) == null) {
			return null;
		} else {
			return getPlaceDetail(placeName).getString("cityname");
		}
	}
	
	/**
	 * @Description:获取相关地点的城市编号
	 * @author fengshuonan
	 * @since 2.4
	 */
	public static String getCityCode(String cityName){
		String url = "http://restapi.amap.com/v3/config/district?level=province&subdistrict=2&keywords=" + cityName + "&key=0e852f489e43f813b04ee69f728ef685";
		JSONObject jsonObj = HttpTool.loadJson(url);
		if(jsonObj == null){
			return "999";
		}
		JSONArray array = jsonObj.getJSONArray("districts");
		if(array == null || array.size() <= 0){
			return "999";
		}
		JSONObject jsonObject = array.getJSONObject(0);
		if(jsonObj != null){
			return jsonObject.getString("citycode");
		}else{
			return "999";
		}
	}

	/**
	 * @Description: 获取某地区的经纬度
	 * @param placeName 地区名称
	 * @author fengshuonan
	 * @return String 经纬度（例116.31088,39.99281）经度在前纬度在后
	 * @since 2.3.2
	 */
	public static String getLngLatNumString(String placeName) {
		if (getPlaceDetail(placeName) == null) {
			return null;
		} else {
			return getPlaceDetail(placeName).getString("location");
		}
	}

	/**
	 * @Description:从字符串（如116.31088,39.99281）中获取经度
	 * @author fengshuonan
	 * @since 2.3.2
	 */
	public static Double getLongitude(String lngLatNumString) {
		if (ToolUtil.isBlank(lngLatNumString)) {
			return null;
		}
		return Double.valueOf(lngLatNumString.split(",")[0]);
	}

	/**
	 * @Description:从字符串（如116.31088,39.99281）中获取纬度
	 * @author fengshuonan
	 * @since 2.3.2
	 */
	public static Double getLatitude(String lngLatNumString) {
		if (ToolUtil.isBlank(lngLatNumString)) {
			return null;
		}
		return Double.valueOf(lngLatNumString.split(",")[1]);
	}

	/**
	 * @Description: 根据关键字搜索某地区的详细信息
	 * @author fengshuonan
	 * @since 2.3.2
	 */
	public static JSONObject getPlaceDetail(String placeName) {
		String url = UrlMaker.getCityNameUrl(AmapConfig.GAODE_WEB_API_KEY, placeName);
		JSONObject jsonObj = HttpTool.loadJson(url);
		if (jsonObj == null) {
			log.error("获取某地详细信息是出错!AmapApi : getPlaceDetail(),搜索内容为：" + placeName);
			return null;
		}
		JSONArray array = jsonObj.getJSONArray("pois");
		if (array == null || array.size() <= 0) {
			JSONObject suggestion = jsonObj.getJSONObject("suggestion");
			JSONArray cityies = suggestion.getJSONArray("cities");
			if (cityies == null || cityies.size() <= 0) {
				log.error("找不到该地区的详细信息!AmapApi:getPlaceDetail(),搜索内容为：" + placeName);
				return null;
			} else {
				String cityName = cityies.getJSONObject(0).getString("name");
				JSONObject result = AmapApi.getPlaceDetailByNameAndCity(placeName, cityName);
				if (result.isEmpty() || result == null) {
					log.error("找不到该地区的详细信息!AmapApi:getPlaceDetail(),搜索内容为：" + placeName);
					return null;
				} else {
					return result;
				}
			}
		} else {
			return array.getJSONObject(0);
		}
	}

	/**
	 * @Description:根据关键字和城市名称搜索地理信息
	 * @author fengshuonan
	 * @since 2.3.2
	 */
	public static JSONObject getPlaceDetailByNameAndCity(String placeName, String cityName) {
		String url = UrlMaker.getPosiInfoUrl(AmapConfig.GAODE_WEB_API_KEY, placeName, cityName);
		JSONObject jsonObj = HttpTool.loadJson(url);
		if (jsonObj == null) {
			log.error("获取某地详细信息是出错!AmapApi : getPlaceDetailByNameAndCity(),搜索内容为：" + placeName);
			return null;
		}
		JSONArray array = jsonObj.getJSONArray("pois");
		if (array == null || array.size() <= 0) {
			log.error("找不到该地区的所属城市!getPlaceDetailByNameAndCity(),搜索内容为：" + placeName);
			return null;
		} else {
			return array.getJSONObject(0);
		}
	}

	/**
	 * @Description:行驶距离测量（从多个出发点到目的地的距离）
	 * @param origins 多个出发点（坐标对见用“| ”分隔；经度和纬度用","分隔,例如：116.481028,39.989643|114.481028,39.989643|115.481028,39.989643）
	 * @param destination 目的地（经度和纬度用","分隔）
	 * @author fengshuonan 
	 * @return JSONArray 距离的集合
	 * @since 2.4
	 */
	public static JSONArray getOriginsToDestinationDistances(String origins, String destination) {
		String url = UrlMaker.getAmapDistanceUrl(origins, destination);
		JSONObject jsonObj = HttpTool.loadJson(url);
		if (jsonObj == null) {
			log.error("获取行驶距离测量错误!AmapApi : getOriginsToDestinationDistances(),出发地：" + origins + ",目的地：" + destination);
			return null;
		} else {
			JSONArray array = jsonObj.getJSONArray("results");
			if (array == null || array.size() == 0) {
				log.error("获取行驶距离测量错误,获取到的距离结果集为空!AmapApi : getOriginsToDestinationDistances(),出发地：" + origins + ",目的地："
						+ destination);
				return null;
			} else {
				return array;
			}
		}
	}

	/**
	 * @Description: 获取两个点之间的距离
	 * @author fengshuonan
	 * @return 如果获取不到距离返回-1
	 * @since 2.4
	 */
	public static BigDecimal getTwoPointDistance(double lng1, double lat1, double lng2, double lat2) {
		JSONArray dis = getOriginsToDestinationDistances(lng1 + "," + lat1, lng2 + "," + lat2);
		if (dis != null) {
			JSONObject obj = dis.getJSONObject(0);
			if (obj != null) {
				int distance = obj.getInteger("distance");
				return new BigDecimal(distance).divide(new BigDecimal(1000)).setScale(1,BigDecimal.ROUND_UP);
			}
		}
		return new BigDecimal(-1);
	}

	/**
	 * @Description:获取从多个出发地到一个目的地的最快时间
	 * @param origins 出发地，经度和纬度用","分隔,例如：116.481028,39.989643
	 * @param destination 目的地，经度和纬度用","分隔,例如：116.481028,39.989643
	 * @return int 最快到达的分钟数
	 * @author fengshuonan
	 * @since 2.4
	 * 
	 */
	public static int getOriginsToDestinationFastestTime(String origins, String destination) {

		JSONArray array = AmapApi.getOriginsToDestinationDistances(origins, destination);
		int fastestDuration = 0;
		if (array != null) {
			for (int i = 0; i < array.size(); i++) {
				JSONObject obj = array.getJSONObject(i);
				int duration = Integer.valueOf(obj.getString("duration"));
				if (i == 0) {
					fastestDuration = duration;
				}
				if (duration < fastestDuration) {
					fastestDuration = duration;
				}
			}
			return fastestDuration / 60;
		}

		return 0;
	}

	/**
	 * @Description:获取从多个出发地到一个目的地的最快时间
	 * @author fengshuonan
	 * @since 2.4
	 */
	public static int getOriginsToDestinationFastestTime(double lng, double lat, List<GetDistanceDto> list) {
		StringBuilder origins = new StringBuilder();
		String destination = lng + "," + lat;

		for (int i = 0; i < list.size(); i++) {
			GetDistanceDto dto = list.get(i);
			if (i != list.size() - 1) {
				origins.append(dto.getLongitude() + "," + dto.getLatitude() + "|");
			} else {
				origins.append(dto.getLongitude() + "," + dto.getLatitude());
			}
		}

		return getOriginsToDestinationFastestTime(origins.toString(), destination);
	}
	
	public static void main(String[] args) {
		System.out.println(getPlaceDetail("秦始皇兵马俑"));
	}
}
